'/
' MOTEP - Massive Online Text Environment Project
' --------------------------------------------------------------------------------
' MOTEP Client
' 
' Main.bmx
' 
' (c) Anton Berlin. All Rights Reserved.
'/


strict

import bah.raknet
import "..\icon.o"

include "Main_h.bmx"
include "..\Framework\Sha256.bmx"
include "..\Shared\Strings.bmx"
include "..\Shared\Keycodes_h.bmx"
include "..\Shared\World.bmx"
include "..\Shared\Character.bmx"
include "..\Shared\Console.bmx"
include "..\Shared\NetUtil.bmx"
include "Master.bmx"
include "..\Shared\Output.bmx"
include "GUI.bmx"
include "Commands.bmx"
include "Netcode.bmx"

'// User interface objects.
global interface_in_game:TInterface = CreateInterface()
global interface_login:TInterface = CreateInterface()
global interface_realmStyle:TInterface = CreateInterface()
global interface_charList:TInterface = CreateInterface()

'// Network stuff.
global masterAddress:string
global masterPort:int
global localPort:int= 0
global connectTimeOutMs:int = 3000

'// Master object.
global Master:TMaster = new TMaster

'// World objects.
global World:TWorld = new TWorld
global Character:TCharacter = new TCharacter
global Region1:TRegion = new TRegion

'// The file stream for the logfile.
global logHandle:TStream

'// Screen settings.
global res_x:int = 800
global res_y:int = 600
global depth:int = 16 '// 0 = Windowed, 32 = Fullscreen
global hz:int = 85 '// Refresh rate

'// Set application title.
AppTitle = APP_TITLE

'// Call the main function.
main()



'// -----------------------------------------------------------------------------------------------------------------
'// Description:
'// 		Main function.
'// -----------------------------------------------------------------------------------------------------------------
function main()

	'// Set the random seed to milliseconds.
	SeedRnd(MilliSecs())
	
	'// Graphical stuff.
	Graphics(RES_X, RES_Y, DEPTH, HZ)
	SetBlend(ALPHABLEND)
	
	'// Hide the mouse.
	HideMouse()
	
	'// Open the log stream for writing.
	if (FileType(LOG_FILE) = 0) then
	
		local success:int = CreateFile(LOG_FILE) 
		if (not success) ..
			RuntimeError("Could not create file ~q" + LOG_FILE + "~q.") 
	
	end if
	logHandle = WriteStream(LOG_FILE)
	if (not logHandle) then
	
		RuntimeError("Could not load ~q" + LOG_FILE + "~q to memory.") 
		return 0
	
	end if
	
	'// Begin the log.
	outLog("Log initiated.")
	outLog(APP_TITLE + " - Startup: " + CurrentTime() + " " + CurrentDate())
	outLog(DOUBLE_DASH_BAR)
	outLog("")
	
	'// Initialize the master object.
	Master.Initialize()
	
	'// Flush input.
	flushInput()
	
	'// Load fonts to memory.
	loadFonts()
	
	'// Load mouse to memory.
	loadMouse()
	
	'// Create user interfaces.
	outLog("Creating user interfaces.")
	Master.in_game = 0
	ListAddLast(interfaceList, interface_in_game)
	ListAddLast(interfaceList, interface_login)
	ListAddLast(interfaceList, interface_realmStyle)
	ListAddLast(interfaceList, interface_charList)
	interface_login.ActivateLayer(1)
	interface_realmStyle.AccessLayer(1).m_visible = 0
	interface_charList.AccessLayer(1).m_visible = 0
	
	'// Build login-interface.
	Master.BuildUserInterface(UI_LOGIN)
	
	'// Center the mouse.
	CenterMouse()
	
	'// Create the peers.
	outLog("Creating peers.")
	for local i:int = 0 to 1
		clientPeer[i] = TRKRakNetworkFactory.GetRakPeerInterface(); next
	
	'// Main loop.
	while (not Master.m_stopEvent and not AppTerminate()) 
	
		Delay(2) '// Let other applications get CPU power as well.
		Master.Run()
	
	end while
	
	outLog("")
	outLog(DASH_BREAK)
	outLog("Exited main loop.")
	
	'// End the log.
	outLog("")
	outLog(DOUBLE_DASH_BAR)
	outLog("Log ended: " + CurrentTime() + " " + CurrentDate())
	
	'// Close connections.
	for local peer:int = 0 until clientPeer.length
	
		if (clientPeer[peer]) then
		
			clientPeer[peer].Shutdown(peerShutdownTime)
			TRKRakNetworkFactory.DestroyRakPeerInterface(clientPeer[peer])
		
		end if
	
	next
	
	'// Close the log stream.
	CloseStream(logHandle) 
	
	Delay(200)

end function

'// -----------------------------------------------------------------------------------------------------------------
'// Description:
'// 		Clear the backbuffer, render to the backbuffer, and then show the backbuffer.
'// 
'// Parameters:
'// 		(byte) in_game: Whether or not we are in-game.
'// -----------------------------------------------------------------------------------------------------------------
function renderFrame(in_game:byte = false)

	Cls() '// Clear the screen for the next frame.
	drawFrame(in_game)
	Flip() '// Flip the buffers.

end function

'// -----------------------------------------------------------------------------------------------------------------
'// Description:
'// 		Draw the next frame to the backbuffer.
'// 
'// Parameters:
'// 		(byte) in_game: Whether or not we are in-game.
'// -----------------------------------------------------------------------------------------------------------------
function drawFrame(in_game:byte = false)

	if (in_game) ..
		drawFrame_Game() ..
	else ..
		drawFrame_Menu()

end function

'// -----------------------------------------------------------------------------------------------------------------
'// Description:
'// 		Get the master-server address.
'// -----------------------------------------------------------------------------------------------------------------
function getMasterAddress:string()

	local mservIP:string = null
	local fileHandle:TStream = ReadStream(ADDRESS_FILE)
	
	if (not fileHandle) then
	
		outErr("Could not load ~q" + ADDRESS_FILE + "~q.")
		return null
	
	end if
	
	mservIP = ReadLine(fileHandle)
	CloseStream(fileHandle)
	
	if (not mservIP) then
	
		outErr("Could not load server ip from ~q" + ADDRESS_FILE + "~q.")
		return null
	
	end if
	
	return mservIP

end function

'// -----------------------------------------------------------------------------------------------------------------
'// Description:
'// 		Write a line into the log.
'// 
'// Parameters:
'// 		(string) str: A string to write into the log.
'// -----------------------------------------------------------------------------------------------------------------
function outLog(str:string); WriteLine(logHandle, str); end function

'// -----------------------------------------------------------------------------------------------------------------
'// Description:
'// 		Write a line into the log and output it to standard output as well.
'// 
'// Parameters:
'// 		(string) str: A string to write into the log and to output to the standard output.
'// -----------------------------------------------------------------------------------------------------------------
function outErr(str:string)

	outLog("ERROR: " + str)
	Print("ERROR: " + str)

end function
